

package control;

import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.Timer;
import model.Account;
import model.Share;
import model.Time;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.StandardXYItemRenderer;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.data.time.Day;
import org.jfree.data.time.FixedMillisecond;
import org.jfree.data.time.Hour;
import org.jfree.data.time.Millisecond;
import org.jfree.data.time.RegularTimePeriod;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.ui.ApplicationFrame;
  
public class StatChartController extends ApplicationFrame implements ActionListener {

    private Account account;
    private Share share;
    private Time time; 
   
    private Calendar calendar = Calendar.getInstance();
    private SimpleDateFormat dateFormat = new SimpleDateFormat("hh:mm:ss");
      
    private String timestamp; 
    private TimeSeries series1;
    private double incrementSerie1;
    private TimeSeries series2;
    private double incrementSerie2;
    private TimeSeries series3;
    private double incrementSerie3;
    private TimeSeries series4;
    private double incrementSerie4;
    private TimeSeries series5;
    private double incrementSerie5;
    private TimeSeries series6; 
    private double incrementSerie6; 
    
    private int interval;
    private Timer timer;
    private int chronometer; 
    
    private int countForward;
    
    final JButton jbPlay = new JButton("Começar");
    final JButton jbStop = new JButton("Parar");
    final JButton jbForward = new JButton("Avançar Periodo");
    final JProgressBar jpbTimerPeriod = new JProgressBar(0,4);
           
    /** The plot. */
    private XYPlot plot;
   
    /** The index of the last dataset added. */
    private int datasetIndex = 0;
    
    public StatChartController(Account controlledAccount, Share controlledShare, Time controlledTime) {

        super("EconomyLabs");
        setAccount(controlledAccount);
        setShare(controlledShare);
        setTime(controlledTime);
        setInterval(getTime().getInterval());
        //grafico
        final XYDataset dataset = createDataset();

        final NumberAxis rangeAxis = new NumberAxis("Periodo");
        rangeAxis.setRange(0, 10);

        final NumberAxis domainAxis = new NumberAxis("Preço");
        //domainAxis.setInverted(true);
        domainAxis.setAutoRangeIncludesZero(true);
        domainAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());

        final XYItemRenderer renderer = new StandardXYItemRenderer();

        //final XYPlot plot = new XYPlot(dataset, domainAxis, rangeAxis, renderer);
        this.plot = new XYPlot(dataset, domainAxis, rangeAxis, renderer);
        
        //this.plot = chart.getXYPlot();
        plot.setOrientation(PlotOrientation.HORIZONTAL);
        final JFreeChart chart = new JFreeChart("Mercado de Ativos", plot);

        /*
        final XYSeriesCollection dataset = createZeroDataset("0");
        XYDataset dataset = createSampleDataset();
        final JFreeChart chart = ChartFactory.createXYLineChart("Mercado de Ativos",
            "X", 
            "Y", 
            dataset,
            PlotOrientation.VERTICAL,
            true,
            true,
            false);
        chart.setBackgroundPaint(Color.white);
        
        this.plot = chart.getXYPlot();
        this.plot.setBackgroundPaint(Color.lightGray);
        this.plot.setDomainGridlinePaint(Color.white);
        this.plot.setRangeGridlinePaint(Color.white);
//        this.plot.setAxisOffset(new Spacer(Spacer.ABSOLUTE, 4, 4, 4, 4));
        final ValueAxis axis = this.plot.getDomainAxis();
        axis.setAutoRange(true);

        final NumberAxis rangeAxis2 = new NumberAxis("Range Axis 2");
        rangeAxis2.setAutoRangeIncludesZero(false);
        */
        final ChartPanel chartPanel = new ChartPanel(chart);
        //fim do grafico
        
        jbForward.setActionCommand("FORWARD");
        jbForward.setIcon( new ImageIcon("images/media/StepForward24.gif")); 
        jbForward.setBackground(Color.WHITE);
        jbForward.addActionListener(this);
        jbForward.setEnabled(false); 
         
        jbPlay.setActionCommand("PLAY");        
        jbPlay.setIcon( new ImageIcon("images/media/Play24.gif"));
        jbPlay.setBackground(Color.WHITE);
        jbPlay.addActionListener(this);
        
        
        jbStop.setActionCommand("STOP");
        jbStop.setIcon( new ImageIcon("images/media/Pause24.gif")); 
        jbStop.setBackground(Color.WHITE);
        jbStop.addActionListener(this);
        jbStop.setEnabled(false); 
        
        //set swing panel
        JPanel gridBagPanel = new JPanel();
        GridBagConstraints gridBagConstraints;

        gridBagPanel.setLayout(new java.awt.GridBagLayout());        
        chartPanel.setPreferredSize(new java.awt.Dimension(500, 438));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;      
        gridBagPanel.add(chartPanel, gridBagConstraints);
        
        //Jbuttonnnnsssss
        JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout(new java.awt.FlowLayout()); 
        jbPlay.setPreferredSize(new java.awt.Dimension(150, 30));     
        buttonPanel.add(jbPlay);        
        jbForward.setPreferredSize(new java.awt.Dimension(150, 30));           
        buttonPanel.add(jbForward);        
        jbStop.setPreferredSize(new java.awt.Dimension(150, 30));         
        buttonPanel.add(jbStop);          
        buttonPanel.setPreferredSize(new java.awt.Dimension(500, 50));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;      
        gridBagPanel.add(buttonPanel, gridBagConstraints);
        
        setContentPane(gridBagPanel);
         
    }

    /**
     * Creates a sample dataset.
     * 
     * @return A dataset.
     */
    private XYDataset createDataset() {
        XYSeries series1 = new XYSeries("Series 1");
        for( int u=1; u<=10;u++){
            series1.add(u,u+getTime().getPeriod());
        }
        XYSeries series2 = new XYSeries("Series 2");
        for( int u=1; u<=10;u++){
            series2.add(u,u+getTime().getPeriod()+1);
        }
        XYSeriesCollection dataset = new XYSeriesCollection();
        dataset.addSeries(series1);
        dataset.addSeries(series2);
        return dataset;
    }
    /**
     * Creates a random dataset.
     * 
     * @param name  the series name.
     * 
     * @return The dataset.
     */
    private XYSeriesCollection createRandomDataset(final String name) {
        final XYSeries series = new XYSeries("Random Data");
        series.add(1.0, 1+getTime().getPeriod());
        series.add(2.0, 2);
        series.add(3.0, 3);
        series.add(4.0, 4);
        series.add(5.0, 5);
        series.add(6.0, 6);
        series.add(7.0, 7);
        series.add(8.0, 7);
        series.add(9.0, 9);
        return new XYSeriesCollection(series);
    }
     
    private XYSeriesCollection createZeroDataset(final String name) {
        final XYSeries series = new XYSeries("Random Data");
        for( int u=1; u<=10;u++){
            series.add(u,null);
        }
         
        return new XYSeriesCollection(series);
    }

    private void updatePlotSeries( ){
        final XYDataset dataset = createDataset();

        this.plot.setDataset( 1,  dataset );
        this.plot.setRenderer(1, new StandardXYItemRenderer());
        this.plot.setDataset( 2,  dataset );
        this.plot.setRenderer(2, new StandardXYItemRenderer());
        /*
        if (this.datasetIndex < 10) {
                this.datasetIndex++;
                this.plot.setDataset( this.datasetIndex, createRandomDataset("b" + this.datasetIndex) );
                this.plot.setRenderer(this.datasetIndex, new StandardXYItemRenderer());
            }
        /* 
        final Millisecond now = new Millisecond() ;
        getSeries1().add(now, incrementSerie1 );
        getSeries2().add(now, incrementSerie2 );
        getSeries3().add(now, incrementSerie3 );
        getSeries4().add(now, incrementSerie4 );
        getSeries5().add(now, incrementSerie5 );
        getSeries6().add(now, incrementSerie6 );
        */
    }
     
     
    private void restartClock(){
            
        chronometer = 0;
        timer.start(); 
    }
     
    private void startClock(){
         
         //repete acao a cada 1000 milisegundos
        timer = new Timer(1000, new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                if (chronometer == getTime().getInterval()) {                  
                    forward(); 
                    restartClock(); 
                }
                 
                chronometer++;
                getTime().setTimestamp(getStringClock());
                getTime().timerCounter(chronometer);
                //updatePlotSeries();
                incrementSerie1 += ((getShare().getPurchasePrice(0)*(getShare().getVariation(0)/100))/getInterval()); 
                incrementSerie2 += ((getShare().getPurchasePrice(1)*(getShare().getVariation(1)/100))/getInterval());
                incrementSerie3 += ((getShare().getPurchasePrice(2)*(getShare().getVariation(2)/100))/getInterval());
                incrementSerie4 += ((getShare().getPurchasePrice(3)*(getShare().getVariation(3)/100))/getInterval());
                incrementSerie5 += ((getShare().getPurchasePrice(4)*(getShare().getVariation(4)/100))/getInterval());
                incrementSerie6 += ((getShare().getPurchasePrice(5)*(getShare().getVariation(5)/100))/getInterval());
                
                }
        });
        
        chronometer = 0;
        timer.start(); 
          
    }
   
    private void stopClock(){

        chronometer = 0; 
        getTime().timerCounter(chronometer);
        timer.stop(); 
        
    }
   
    private String getStringClock() {
          
        calendar.setTimeInMillis(System.currentTimeMillis());
        String strClock = dateFormat.format(calendar.getTime());
        return strClock;
    }
    
    private JFreeChart createChart(final XYDataset dataset) {
        final JFreeChart result = ChartFactory.createTimeSeriesChart(
            "", 
            "Periodo", 
            "Preço $",
            dataset, 
            true, 
            true, 
            false
        );
        final XYPlot plot = result.getXYPlot();
        ValueAxis axis = plot.getDomainAxis();
        axis.setAutoRange(true);
         
        //axis.setFixedAutoRange(30000.0*10*10);  // 60 seconds
        axis = plot.getRangeAxis();
        //axis.setRange(90.0, 110.0); 
        return result;
    }
       
    public void actionPerformed(final ActionEvent e) {
        if (e.getActionCommand().equals("FORWARD")) {
           forward(); 
        }
        
        if (e.getActionCommand().equals("PLAY")) {
            play();
        }
        
        if (e.getActionCommand().equals("STOP")) {
            stop();
        }
    }
      
    public void play(){
        this.countForward=0;
       
        getTime().play(); 
        getAccount().play();
        getShare().play();
        startClock(); 
        jbPlay.setEnabled(false);
        jbStop.setEnabled(true);
        jbForward.setEnabled(true);
         //add control for loop
        
       for( int t = 0; t < 3 ; t++){
           //forward();
           
            try {
                Thread.sleep(100);
            } catch (InterruptedException ex) {
                Logger.getLogger(StatChartController.class.getName()).log(Level.SEVERE, null, ex);
            }
       }
        
    }
    
    public void stop(){
        JOptionPane.showMessageDialog(rootPane, "sssss");
         
              
        jbPlay.setEnabled(true);
        jbStop.setEnabled(false);
        jbForward.setEnabled(false);
           
        
        getTime().stop();
        getShare().stop();
        getAccount().stop();
        
        stopClock();
        this.countForward=0;
        
    }
    
    public void forward(){
        this.countForward++;
                
        int mp = getShare().getMaxPeriod()+1;
          
        if( countForward==mp ){
           
        }
         
        getTime().forward( getTime().getPeriod(), getTime().getTimestamp() );
        getShare().forward( getTime().getPeriod() );
        getAccount().forward( getTime().getPeriod(), getShare().getShareTable() );
         
        updatePlotSeries();
        restartClock();
          
    }
    
    public void setTime(Time time) {
        this.time = time;
    }
  
    public void setAccount(Account account) {
        this.account = account;
    }

    public void setShare(Share share) {
        this.share = share;
    }
 
    public Share getShare() {
        return share;
    }

    public Account getAccount() {
        return account;
    }

    public Time getTime() {
        return time;
    }

    public TimeSeries getSeries1() {
        return series1;
    }

    public void setSeries1(TimeSeries series1) {
        this.series1 = series1;
    }

    public TimeSeries getSeries2() {
        return series2;
    }

    public void setSeries2(TimeSeries series2) {
        this.series2 = series2;
    }

    public TimeSeries getSeries3() {
        return series3;
    }

    public void setSeries3(TimeSeries series3) {
        this.series3 = series3;
    }

    public TimeSeries getSeries4() {
        return series4;
    }

    public void setSeries4(TimeSeries series4) {
        this.series4 = series4;
    }

    public TimeSeries getSeries5() {
        return series5;
    }

    public void setSeries5(TimeSeries series5) {
        this.series5 = series5;
    }

    public TimeSeries getSeries6() {
        return series6;
    }

    public void setSeries6(TimeSeries series6) {
        this.series6 = series6;
    }

    public String getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(String timestamp) {
        this.timestamp = timestamp;
    }
    
    public int getInterval() {
        return interval;
    }

    public void setInterval(int interval) {
        this.interval = interval;
    }
}